<!--
  <SwipePagination
    v-model="目前分頁"
    :canSwipe="是否靠滑動換頁(boolean: default true)"
    :canSwipeLeft="是否可以操作往左滑(boolean: default true)"
    :canSwipeRight="是否可以操作往右滑(boolean: default true)"
  >
    {{ default slot (as known as page-1) }}

    <template #page-2="{ active }">
      {{ page-2 slot }}
    </template>

    <template #page-3="{ active }">
      {{ page-3 slot }}
    </template>
  </SwipePagination>


  目前限定最多三頁
-->
<template>
  <div class="swipe-pagination" :class="{ swiping }" ref="root">
    <!-- page-1 -->
    <div
      class="page"
      :class="{ 'no-transition': disableTransition, out: page > 1 }"
      :style="{ transitionDuration, transform: page1TranslateX }"
      @transitionend="resetTransitionDuration"
    >
      <slot></slot>
    </div>

    <!-- page-2 -->
    <div
      class="page"
      v-if="$slots['page-2']"
      :class="{ 'no-transition': disableTransition, ready: page < 2, out: page > 2 }"
      :style="{ transitionDuration, transform: page2TranslateX }"
      @transitionend="resetTransitionDuration"
    >
      <slot name="page-2" :active="page2Active"></slot>
    </div>

    <!-- page-3 -->
    <div
      class="page"
      v-if="$slots['page-3']"
      :class="{ 'no-transition': disableTransition, ready: page < 3 }"
      :style="{ transitionDuration, transform: page3TranslateX }"
      @transitionend="resetTransitionDuration"
    >
      <slot name="page-3" :active="page3Active"></slot>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, ref, useSlots } from 'vue'
import { usePreventTouchmove } from '@/compositions/mobile/preventTouchmove'
import { useSwipe } from '@/compositions/mobile/swipe'

const props = defineProps({
  // 父元件綁定目前分頁
  modelValue: { type: Number, required: true },

  // 是否使用滑動換頁
  canSwipe: { type: Boolean, default: true },

  // 單獨限制往左或往右滑動換頁
  canSwipeLeft: { type: Boolean, default: true },
  canSwipeRight: { type: Boolean, default: true },

  disableTransition: { type: Boolean, default: false },
})

const emits = defineEmits(['update:modelValue'])

const root = ref(null)
const slots = useSlots()

// 目前限制為三頁
const FIRST_PAGE = 1
const LAST_PAGE = (() => {
  if (slots['page-3']) {
    if (!slots['page-2']) {
      console.warn(
        `Your SwipePagination component declare page-3 but no page-2. Please declare page-2 first before page-3`,
      )
    }
    return 3
  } else if (slots['page-2']) {
    return 2
  }
  return 1
})()

let HALF_VIEW_WIDTH = 200
onMounted(() => (HALF_VIEW_WIDTH = root.value.clientWidth / 2))

// 目前分頁
const page = computed({
  get: () => props.modelValue,
  set: (newPage) => emits('update:modelValue', newPage),
})

// 滑動操作
const { offset, swiping, transitionDuration, resetTransitionDuration } = useSwipe(root, {
  isBlockBackward: () => page.value === FIRST_PAGE || !props.canSwipe || !props.canSwipeRight,
  isBlockForward: () => page.value === LAST_PAGE || !props.canSwipe || !props.canSwipeLeft,
  onBackward: () => (page.value -= 1),
  onForward: () => (page.value += 1),
})

// 滑動中關閉瀏覽器預設行為
usePreventTouchmove(root, () => offset.value !== 0)

// 觸控滑動時移動的距離
const swipeLeft = computed(() => offset.value > 0)
const swipeRight = computed(() => offset.value < 0)

// 觸控滑動時的樣式
// 上層移動 100% ~ 0%
const topTtranslateX = computed(() => {
  if (swiping.value) {
    if (swipeLeft.value) {
      const _offset = Math.min(offset.value, HALF_VIEW_WIDTH * 2)
      return `translateX(calc(100% - ${_offset}px))`
    }
    if (swipeRight.value) {
      const _offset = Math.min(-offset.value, HALF_VIEW_WIDTH * 2)
      return `translateX(${_offset}px)`
    }
  }
  return ''
})
// 下層移動 0% ~ -30%
const bottomTranslateX = computed(() => {
  if (swiping.value) {
    if (swipeLeft.value) {
      const _offset = Math.min(offset.value, HALF_VIEW_WIDTH * 2)
      const dist = Math.floor(-_offset * 0.3)
      return `translateX(${dist}px)`
    }
    if (swipeRight.value) {
      const _offset = Math.min(-offset.value, HALF_VIEW_WIDTH * 2)
      const dist = Math.floor(_offset * 0.3)
      return `translateX(calc(-30% + ${dist}px))`
    }
  }
  return ''
})

const page1TranslateX = computed(() => {
  if ((page.value === FIRST_PAGE && swipeLeft.value) || (page.value === FIRST_PAGE + 1 && swipeRight.value)) {
    return bottomTranslateX.value
  }
  return ''
})
const page2TranslateX = computed(() => {
  if (page.value === 1) {
    return topTtranslateX.value
  }
  if (page.value === 2 && swipeRight.value) {
    return topTtranslateX.value
  }
  if (page.value === 2 && swipeLeft.value) {
    return bottomTranslateX.value
  }
  if (page.value === 3) {
    return bottomTranslateX.value
  }
  return ''
})
const page3TranslateX = computed(() => {
  if ((page.value === LAST_PAGE - 1 && swipeLeft.value) || (page.value === LAST_PAGE && swipeRight.value)) {
    return topTtranslateX.value
  }
  return ''
})

// 分頁是否開啟
const page2Active = computed(() => page.value >= 2 || (swipeLeft.value && page.value === 1))
const page3Active = computed(() => page.value >= 3 || (swipeLeft.value && page.value === 2))
</script>

<style lang="scss" scoped>
.swipe-pagination {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;

  &.swiping {
    .page {
      transition: none;
      will-change: transform;
    }
  }

  .page {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    transition: transform 0.25s ease-out;
    overflow: auto;
    scroll-behavior: smooth;

    &.no-transition {
      transition: none;
    }
    &.out {
      transform: translateX(-30%);
    }
    &.ready {
      transform: translateX(100%);
    }
  }
}
</style>
